#include "deembed.h"
#include <math.h>
#ifdef DEBUG
#include <stdio.h>
#endif
#include <stdlib.h>

void diff_classification_CH(
			 difference_class **m,
			 class_count *cc,
			 int **d,
			 unsigned char **a,
			 unsigned int h,
			 unsigned int w
			 )
{
  cc->n_CH = 0;
  int i, j, x, b;
  for(i=0; i<h; ++i)
    for(j=0; j<w; ++j) {
      x = MIN(2*(255 - a[i][j]), 2*a[i][j] + 1);
      b = d[i][j] >= 0;
      if(abs(2 * ((int)floor((float)d[i][j] / 2)) + b) <= x) {
	//is changeable
	m[i][j] = CH;
	cc->n_CH++;
      }
      else
	m[i][j] = NC;
    }
}

void extract_bitstream(
		    unsigned char *b,
		    int **d,
		    difference_class **dc,
		    unsigned int height,
		    unsigned int width
		    )
{
  int i, j, k=0;
  for(i=0; i<height; ++i)
    for(j=0; j<width; ++j)
      if(dc[i][j] == CH)
	b[k++] = d[i][j] & 1;
}

unsigned char *restore_differences(
				   int **differences,
				   unsigned int height,
				   unsigned int width,
				   unsigned char *bitstream,
				   difference_class **membership,
				   unsigned char *lm
				   ) {
  int i, j, t=0, k=0;
  for(i=0; i<height; ++i)
    for(j=0; j<width; ++j) {
      int d = differences[i][j];
      if(membership[i][j] == CH) {
	if(lm[i*width + j]) {
	  //expanded difference
	  differences[i][j] = floor((double)d / 2);
	  ++k;
	}
	else {
	  //location map is 0
	  if(d == 0 || d == 1)
	    differences[i][j] = 1;
	  else
	    if(d == -2 || d == -1)
	      differences[i][j] = -2;
	    else {
	      //restore LSB
	      int b = *(bitstream++);
	      differences[i][j] = 2 * (int)floor((double)d / 2) + b;
	      ++t;
	    }
	}
      }
    }
#ifdef DEBUG
  printf("detected expanded differences: %d\n", k);
  printf("LSB read from the bitstream: %d\n", t);
#endif

  return bitstream;
}
	      
	    
